Skip to content

feat(web): add project sidebar accents - #7972

Closed
msegec wants to merge 18 commits into
pingdotgg:mainfrom
msegec:feat/project-sidebar-accents
Closed

feat(web): add project sidebar accents#7972
msegec wants to merge 18 commits into
pingdotgg:mainfrom
msegec:feat/project-sidebar-accents

Conversation

@msegec

@msegec msegec commented Aug 23, 2026

Copy link
Copy Markdown

What changed

Projects can define a checked-in sidebar accent in t3.json.

  • Simple mode accepts one six-digit hex color and generates restrained idle, hover, and selected tints.
  • Advanced mode accepts exact idle, active, and selected colors.
  • The tint is strongest at the right edge of the row and fades out toward the left, staying visible while idle. Selection strengthens it, hover leaves it unchanged, and there is no dot, strip, animation, or transition.
  • The existing project favicon response carries the accent, so sidebar rows do not make another request.

This applies to the web sidebar and desktop wrapper. The legacy sidebar (still reachable via its setting) and the separate mobile thread list are deliberately unchanged.

Why

Project icons are easy to miss when the sidebar contains threads from several repositories. A persistent, low-contrast tint makes project groups faster to identify while keeping the existing row layout and interaction states.

UI changes

The T3 Code repository uses #1688f0 and masterrulez uses #F2A93B, both in simple mode, in the after view.

Before After
Sidebar thread rows before project accent colors Thread rows with project accent gradients fading in from the right edge

Verification

  • 60 focused contract, shared, server, asset, and web tests pass.
  • Contracts, shared, server, and web typechecks pass.
  • Targeted lint and git diff --check pass.
  • Checked idle and selected states in an isolated real-app preview using copied project data.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before and after screenshots
  • No animation or motion was added, so a video is not applicable

Made with Claude Fable 5 using the Claude Code harness.


Note

Medium Risk
Shell snapshot and stream paths now do concurrent per-project t3.json reads, and wire schemas gain optional accent; failures degrade to null but load and strict decoders should be aware.

Overview
Adds optional accentColor in t3.json (single six-digit hex or explicit idle / active / selected palette) and threads the resolved value onto orchestration project payloads as accent, read from disk when shell snapshots and project-upsert events are built—not stored in the projection.

Server: ProjectFaviconResolver gains resolveAccent and layerLive; ProjectAccents attaches accent (always present, null when cleared or unreadable) on HTTP shellSnapshot, the WebSocket shell snapshot load, and live project-upserted events. OrchestrationProject / OrchestrationProjectShell contracts pick up optional accent.

Web: Sidebar and search rows map project.accent into CSS variables and data-project-accent* attributes for a right-edge gradient (idle / selected / active; hover unchanged), plus small focus-visible and tooltip-delay tweaks. Docs and repo t3.json document the feature.

Reviewed by Cursor Bugbot for commit c5f18f0. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add project sidebar accents resolved from t3.json

  • Adds an optional accentColor field to the t3.json schema, accepting a single hex color or a full palette (idle, active, selected).
  • Extends ProjectFaviconResolver with resolveAccent and adds ProjectAccents helpers to attach accents to project records concurrently (limit 16). Resolver errors yield null.
  • The shellSnapshot HTTP handler and WebSocket shell stream now include the accent field on project payloads.
  • Sidebar thread rows and search result rows render a fading accent gradient using inline CSS variables and data-project-accent attributes, with distinct colors for idle, selected, and active states.
  • Risk: OrchestrationProject and OrchestrationProjectShell schemas in orchestration.ts gain an optional nullable accent field; consumers with strict decoding must accept it.

Macroscope summarized c5f18f0.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 97021ee8-d582-4c48-a235-a86daa127c8f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 23, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the sidebar project-accent styling for consistency with the existing row surface model and CSS ownership rules. Three findings, all in the new accent styling: the accent rules are scoped to an ancestor attribute that does not exist in the mobile sidebar, the hover rule is not pointer-gated like the row's Tailwind hover: utilities, and the accent state attribute collapses route-active and multi-select into one surface.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/index.css Outdated
Comment thread apps/web/src/index.css Outdated
Comment thread apps/web/src/components/Sidebar.tsx Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a new project configuration and propagates it through shared contracts, live server snapshot/WebSocket assembly, and multiple sidebar rendering paths, including new filesystem work on existing requests. The change is cross-cutting and has an unresolved external review concern, so its behavior and integration should receive human validation.

You can add or adjust custom eligibility rules. Learn more.

@msegec

msegec commented Aug 24, 2026

Copy link
Copy Markdown
Author

Thank's Theo and team for making such a good 'wrapper', I am greatly enjoying it vs most other tools.

I hope my PRs are not junk. Here is a screenshot of how my client currently looks using it, I decided to run my own branch so if PRs dont get accepted I can still keep my own 'flavor' while still holding tightly to your original path and project.

image image

msegec and others added 2 commits August 24, 2026 21:27
Project icons are easy to miss in a busy sidebar. Checked-in accent colors keep each project's thread rows identifiable across idle, hover, and selected states.
…select

The accent rules required a [data-app-sidebar] ancestor that the mobile
sheet sidebar never renders, the bare :hover left sticky tints on touch
pointers, and routed-active plus multi-selected rows collapsed into one
surface. Drop the ancestor scope, gate :hover behind (hover: hover), and
emit distinct active and selected states mixed over their own row tokens.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@msegec
msegec force-pushed the feat/project-sidebar-accents branch from 34f80a0 to f2082f3 Compare August 24, 2026 13:29
@msegec

msegec commented Aug 26, 2026

Copy link
Copy Markdown
Author

I updated to gradient as it looks a little more slick. Thoughts?

msegec added 3 commits August 26, 2026 14:29
The first gradient pass only overlaid a weak tint on the flat state
surfaces, so hover and selected rows still read as solid fills and the
accent was near invisible. Accented rows now drop the flat row-class
background and paint one gradient per state, holding full strength over
the right quarter, with stronger mix percentages to offset the fade.
Replacing the hover surface with the bare gradient left the hover text
brightening on receded rows standing alone, which read as a font flash.
Hover now paints the standard flat row wash with the accent gradient on
top; selected and active rows keep the full fade.
The thread row tooltip opened after 150ms with a 400ms grouping window,
so moving the pointer down the sidebar flashed the glass info card over
the chat area on nearly every row. Open delay is now 600ms with grouping
off: a sweep never opens it, a deliberate dwell still does.

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the exact-palette path: the routed-thread and multi-selection states resolve to the same color, so the "open thread" cue disappears for projects that set exact accent colors. The earlier mobile-scope, pointer-gating, and generated active/selected issues all look correctly addressed in this head.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/index.css
Sweeping the pointer down the thread list flickered every row corner: the
timestamp or status swapped to the hover action buttons and back on each
pass, and receded rows flashed their text and favicon bright. The swap
includes discrete position changes a CSS transition-delay cannot hold
back, so a 150ms timer now stamps data-hover-intent on the row and every
hover reveal keys off that attribute instead of raw hover. The attribute
is set imperatively so hovering never re-renders rows. Keyboard
focus-visible reveals and the open snooze popover stay immediate.

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One new finding on the hover-intent migration, plus one earlier finding that is still open.

New: useRowHoverIntent drops the coarse-pointer gate that the hover:/group-hover: variants provided, so touch contacts now reveal the row's hover-only actions (see inline comment).

Still open from the previous review (not re-commented): apps/web/src/index.css[data-project-accent-state="active"] and [data-project-accent-state="selected"] resolve to the same paint in exact-palette mode (both read --project-accent-selected and both zero background-color), so an accented project with an exact palette loses the routed-thread vs multi-selected distinction that bg-sidebar-row-active / bg-sidebar-row-selected keep apart.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/Sidebar.tsx Outdated
Send project accents with shell records so rows paint once. Keep hover feedback immediate and discrete, without timers or animated filters.

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One convention finding: the new ProjectAccents helpers take a ProjectFaviconResolver["Service"] instance as a production parameter instead of acquiring the service from the Effect environment. Details inline.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/project/ProjectAccents.ts Outdated
Comment thread apps/web/src/components/Sidebar.tsx

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One new finding on this head, plus one earlier finding that is still open.

  • apps/web/src/components/Sidebar.tsx: this revision strips transition-opacity / transition-colors (and the motion-reduce:transition-none opt-out) from eight row elements, including ones with no accent involvement (draft-row discard button, in-flight row opacity, unpin and PR-status color transitions), and leaves a comment that still explains the card-row control swap as "cross-fading back". Inline comment below.
  • apps/web/src/index.css (still open, previously flagged, not re-posted): with an exact accentColor palette, [data-project-accent-state="active"] and [data-project-accent-state="selected"] both resolve to var(--project-accent-selected) and both zero background-color, so the routed thread and multi-selected rows become visually identical for accented projects even though projectAccentRowState keeps the states distinct. ProjectAccentPalette has no active entry to distinguish them.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/Sidebar.tsx Outdated
Comment thread packages/contracts/src/orchestration.ts
msegec added 4 commits August 26, 2026 16:10
Keep Effect service dependencies visible in the requirement channel. Production helpers no longer accept resolver instances directly.

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two consistency findings in the sidebar changes. The accent plumbing itself (mobile-sheet scope, distinct active/selected states, hover left as the flat row wash) now looks coherent with the row surface model.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/Sidebar.tsx Outdated
Comment thread apps/web/src/components/Sidebar.tsx

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the accent CSS: zeroing the row's background-color for active/selected removes the flat state fill that rowSurfaceClassName owns, so for accented projects the "which thread is open" surface only exists in the right quarter of the row. Details inline; the rest of the change (state split, no hover coupling, unscoped selector for the mobile sheet, accent riding on the project record) looks consistent with the row model.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/index.css

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One consistency finding on the new sidebar accent wiring: the search-result row derives its accent state from a different condition than the fill it paints, so the generated tint blends toward a token that row never uses. Everything else (state split for active/selected, per-trigger tooltip delay instead of a provider-wide change, unscoped [data-project-accent] so the mobile sheet keeps the tint, retained flat surface fills) looks consistent with the row surface model.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/Sidebar.tsx Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c4936fc. Configure here.

Comment thread apps/web/src/components/Sidebar.tsx
msegec added 2 commits August 26, 2026 17:52
The ProjectAccents comments claimed accents are read live; they attach only
when a snapshot or project-upserted payload is assembled. The user doc example
palette used a near-black idle color that is unreadable on the light theme.

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the search-result row's keyboard-highlight surface was downgraded from bg-sidebar-row-active to bg-sidebar-row-selected, which in the default dark sidebar palette (and the built-in dark theme preset) paints weaker than plain hover. Details inline.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/Sidebar.tsx Outdated
msegec added 2 commits August 27, 2026 08:31
Macroscope flagged the search result rows after the accent refactor:
the keyboard-highlighted row was downgraded from bg-sidebar-row-active
to bg-sidebar-row-selected, which paints weaker than plain hover in the
dark palette (7% vs 8% fills). The highlighted row is the keyboard
cursor, so it goes back to the active fill, matching the pre-accent
behavior.
@t3dotgg

t3dotgg commented Aug 28, 2026

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This adds favicon parsing, checked-in color state, contracts, asset changes, web gradients, docs, and tests across 21 files for decorative sidebar color. Mobile and the legacy sidebar remain different, so the cross-layer cost does not produce consistent behavior.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotgg t3dotgg closed this Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants